package com.bitdf.txing.group.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bitdf.txing.common.interceptor.LoginInterceptor;
import com.bitdf.txing.common.to.UserTo;
import com.bitdf.txing.common.utils.PageUtils;
import com.bitdf.txing.common.utils.R;
import com.bitdf.txing.common.vo.UserInfoVo;
import com.bitdf.txing.group.constant.RedisConstant;
import com.bitdf.txing.group.dao.GroupInfoDao;
import com.bitdf.txing.group.entity.GroupImgEntity;
import com.bitdf.txing.group.entity.GroupInfoEntity;
import com.bitdf.txing.group.entity.GroupMemberEntity;
import com.bitdf.txing.group.feign.EsFeignService;
import com.bitdf.txing.group.service.GroupCategoryService;
import com.bitdf.txing.group.service.GroupImgService;
import com.bitdf.txing.group.service.GroupInfoService;
import com.bitdf.txing.group.service.GroupMemberService;
import com.bitdf.txing.group.to.GroupInfoTo;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service("groupInfoService")
public class GroupInfoServiceImpl extends ServiceImpl<GroupInfoDao, GroupInfoEntity> implements GroupInfoService {
    @Autowired
    GroupCategoryService categoryService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    GroupImgService groupImgService;
    @Autowired
    EsFeignService esFeignService;
    @Autowired
    GroupMemberService groupMemberService;
    @Autowired
    RedissonClient redissonClient;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
//        IPage<GroupInfoEntity> page = this.page(
//                new Query<GroupInfoEntity>().getPage(params),
//                new QueryWrapper<GroupInfoEntity>()
//        );
//
//        return new PageUtils(page);
        return null;
    }


    /**
     * 组团点赞与取消
     *
     * @param groupId
     * @return
     */
    @Override
    public Boolean modifyLikeByGroupId(Long groupId) throws IOException {
        UserInfoVo userInfoVo = (UserInfoVo) StpUtil.getSession().get("user");

        BoundSetOperations<String, String> ops = stringRedisTemplate.opsForSet().getOperations().boundSetOps(RedisConstant.GROUP_LIKE_NAME + groupId);
        String id = userInfoVo.getId().toString();
        Boolean aBoolean = ops.isMember(id);
        Long add;
        if (aBoolean) {
            add = ops.remove(id);
        } else {
            add = ops.add(id);
        }
        if (add == 1) {
//            Long size = ops.size();
            R r = esFeignService.countIncreOrDcre(groupId, aBoolean ? -1 : 1, "likeCount");
            return r.getCode() == 0 ? true : false;
        } else {
            return false;
        }
    }

    /**
     * 组团浏览数增加
     *
     * @param groupId
     * @return
     */
    @Override
    public Boolean modifyViewCount(Long groupId) throws IOException {
        R r = esFeignService.countIncreOrDcre(groupId, 1, "viewCount");
        return r.getCode() == 0 ? true : false;
    }

    /**
     * 发起组团
     *
     * @param groupInfoTo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean saveGroupInfoTo(GroupInfoTo groupInfoTo) throws IOException {

        UserInfoVo userInfoVo = (UserInfoVo) StpUtil.getSession().get("user");
        groupInfoTo.setUserId(userInfoVo.getId());

        GroupInfoEntity info = new GroupInfoEntity();
        groupInfoTo.setPublishTime(new Date());
        groupInfoTo.setCreateTime(new Date());
        groupInfoTo.setCurrentPersonCount(1);
        groupInfoTo.setStatus(1);

        groupInfoTo.setCollectCount(0);
        groupInfoTo.setCurrentPersonCount(0);
        groupInfoTo.setCommentCount(0);
        groupInfoTo.setLikeCount(0);
        groupInfoTo.setViewCount(0);
        groupInfoTo.setStatus(1);

        BeanUtils.copyProperties(groupInfoTo, info);

        this.save(info);
        //保存图片
        boolean b = groupImgService.saveGroupImgs(groupInfoTo.getImgList(), groupInfoTo.getSurfaceImg(), info.getId());

        //新增组团用户
        boolean save = groupMemberService.save(new GroupMemberEntity(info.getId(), userInfoVo.getId(), (byte) 1));

        groupInfoTo.setId(info.getId());
        //上传到es
        R r = esFeignService.productStatusUp(groupInfoTo);
        return r.getCode() == 200 ? true : false;
    }

    /**
     * 将es中的数据同步到数据库
     *
     * @param list
     * @return
     */
    @Override
    public boolean syncDatabase(List<GroupInfoTo> list) throws Exception {
        //上分布式锁，避免feign超时时触发多次调用、会出现并发问题
        RLock lock = redissonClient.getLock("backUpData");
        lock.lock(40, TimeUnit.SECONDS);

        try {
            for (GroupInfoTo info : list) {
                //更新组团的主要信息
                GroupInfoEntity entity = new GroupInfoEntity();
                BeanUtils.copyProperties(info, entity);
                boolean b = this.updateById(entity);
                //TODO 处理一下组团已删除的情况

                //更新组团图片集
                List<GroupImgEntity> imgList = groupImgService.list(new QueryWrapper<GroupImgEntity>().in("group_id", info.getId()));
                List<GroupImgEntity> rmList = null;
                if (imgList != null) {
                    rmList = new ArrayList<>(imgList);
                    for (GroupImgEntity groupImgEntity : imgList) {
                        if (info.getImgList() != null && info.getImgList().contains(groupImgEntity.getImgUrl())) {
                            info.getImgList().remove(groupImgEntity.getImgUrl());
                            rmList.remove(groupImgEntity);
                        }
                    }
                }
                if (rmList != null && rmList.size() > 0) {
                    List<Long> collect = rmList.stream().map(item -> {
                        return item.getId();
                    }).collect(Collectors.toList());
                    // TODO 改了
//                    groupImgService.removeBatchByIds(collect);
                    groupImgService.removeByIds(collect);
                }
                if (info.getImgList() != null && info.getImgList().size() > 0) {
                    for (String s : info.getImgList()) {
                        GroupImgEntity entity1 = new GroupImgEntity(info.getId(), s, (byte) 0);
                        groupImgService.save(entity1);
                    }
                }
                //更改封面图
                GroupImgEntity one = groupImgService.getOne(new QueryWrapper<GroupImgEntity>().eq("group_id", info.getId()).eq("status", 1));
                if (one == null) {
                    GroupImgEntity imgEntity = new GroupImgEntity(info.getId(), info.getSurfaceImg(), (byte) 1);
                    groupImgService.save(imgEntity);
                } else if (!one.getImgUrl().equals(info.getSurfaceImg())) {
                    one.setImgUrl(info.getSurfaceImg());
                    groupImgService.updateById(one);
                }
            }
        } finally {
            //解锁
            lock.unlock();
        }
        return true;
    }


}